// ts中可以给变量指定类型
// 指定类型后，当为变量赋值时，ts编译器会检查值是否符合类型声明，不符合就报错

// 声明一个变量a，同时指定它的类型时number
let a:number;
a=10;
let b:string = '你好啊';

console.log(a,b)


// 如果变量的声明和赋值是同时进行的，ts可以自动对变量进行类型监测，下面的c已经是布尔类型了

let c = true;


// js中的函数是不考虑参数的类型和个数的,ts还能设置返回值的类型
function sum(a:number,b:number):number{
    console.log(a+b)
    return a+b;
 
}
sum(10,20)
 

//如果不把文件当作模块使用的话typescript会认为所有文件里的代码都是在一个作用域里的，所以即使在不同文件也不能声明同名变量
//最简单的解决办法就是关掉js文件(wink~)

// 类型有以下几种
// 1.number 2.string 3.Boolean 4.字面量（限制变量的值就是该字面量的值）5.any（任意类型） 6.unknown（安全类型的any）
// 7.void（没有值(null)或者undefined）8.never（不能是任何值）9.object 10.array 11.tuple（元组，ts新增类型，固定长度数组）12.enum，枚举


// 字面量
let d:10;
d=10;
// d=11就会报错，d只能等于10，这就是字面量

// 如果是这样字面量也能有多个值,这种叫联合类型
let e:'a' | 'b';
e = 'a'
e = 'b'

// 声明变量不赋值也不给类型就是隐式any类型
let f;
f = 10;
f = '你好'

// unKnow类型同样可以让变量接收任意类型的值，any类型的变量可以给任意类型变量赋值，不管符不符合类型，但是unKnow就不能赋值给其他类型，除非你判断
let g:unknown;
g=10;
g='你好'



let h:string;

// unKnow就不能赋值给其他类型，除非你判断
// if(typeof g === "string"){
//     h=g;
// }
// 但上面判断类型太麻烦了，所以我们使用类型断言
// 类型断言，可以告诉解析器变量的实际类型
h = g as string;
// 断言还有个简写
h = <string>g;


// void一般用来设置函数的返回值，函数返回值默认就是void，你把函数返回值设置成void就只能返回null之类的了，不然报错

// 变量可以设置多个类型
let x:string | number;
x=10;
x="你好"

// never也可以用来修饰函数返回值，表示永远不会有返回值


// 对象可以这样写,加个问号表示那个属性可选
let j:{name:string,age?:number}
// 假如你想添加任意个属性，就这样写

let k:{name:string,[xx:string]:any}
// [xx:string]里面xx是变量名，你随便写什么都是可以的，string是属性名类型(就是你之后要添加的属性名字的类型)，any是属性的类型
// 因为js中属性名都是字符串，所以这个[xx:string]相当于任意属性名，加上any就变成了任意名字和类型的属性
k={
    name:'涨啊',
    age:18,
    real:true
}

// 下面这个表示n是一个函数，两个参数，而且返回值也是number类型

// 函数的结构声明
let n:(a:number,b:number)=>number  

n = function(n1:number,n2:number):number{
    return n1+n2;
}

// 声明数组
//string[]表示字符串数组,number[]自然就是number类型数组，还有种写法是这样的let ab:Array<number>
let ab:string[];
ab=['a','b']


// 元组，tuple，表示固定长度的数组

//这个元组两个值，都是string
let ac:[string,string]


// 枚举,把可能的情况都列出来
enum gender{
    male=0,
    female=1
}
let ad:{name:string,sex:gender}
// 性别有这两种可能，所以做个枚举保存，类型给性别
ad = {
    name:'张三',
    sex:gender.male
}


// 同时满足
// 这个例子只能加这两个了
let xc :{name:string} & {age:number}
xc={name:'张三',age:18}



// 类型别名

type myType = string;
// 从现在开始myType就是string
let ui:myType;
ui='你好'
type hj = 1|2|3
let jk:hj;